#!/bin/env python
#-*- coding:utf-8 -*-

#----------------------------------------------------------------------------
# Name     :      GUI.py
# Purpose  :      Mysql tool for ucweb, and this is the py file of gui.
# Author   :      Albert cheng
# Created  :      2012-10-29
# Copyright:     (c) 2012 by Albertcheng
# Licence  :      wxWindows license
#----------------------------------------------------------------------------

import wx
import re
from request_handler import request_mysql,request_sqlite,request_xml
import wx.lib.delayedresult as dr
import sys
import time
 
from gui_grid import GRID_STRING,GRID_NUMBER,GRID_BOOL,GRID_CHOICE,CustTableGrid

        
        
class basePanel(wx.Panel):   
    """
    base panel code.
    
    """
    def __init__(self,parent, log):
        self.proj_def = {
                    0:"ssdz",
                    1:"tianjie",
                    2:"config",
                    }
        
        self.player = {}
        self.nb = parent
        self.timer_interval = 5000
        
        
        self.panel = wx.Panel.__init__(self,parent)
        self.Log = log
        ##=============================================
        # sizer definition
        setattr(self.nb,"tianjie_refresh_mysql_flag",False)
        setattr(self.nb,"ssdz_refresh_mysql_flag",False)
        
        self.sqlite_request = request_sqlite(self.Log)
        self.cfg = self.sqlite_request.get()
        self.db_cfg = self.cfg[0]
        self.prefer_cfg = self.cfg[1][0]
        
        self.mysql_request = request_mysql(self.Log,self.db_cfg)
        
        self.xml_request = request_xml(self.Log)
        self.xml_cfg = self.xml_request.read_cfg()
        
        self.projs = list(set(self.xml_cfg.keys()))
        self.proj_id = self.prefer_cfg[1]
        self.proj = self.projs[self.proj_id]
        
        
        
        
        #self.run_bg_mysql_thread()
        
        #self.base_sizer_manager()

    
    def run_bg_mysql_thread(self, proj):
        setattr(self,("%s_" % proj)+ "refresh_mysql",self.refresh_mysql)
        
        def __run(evt):
            dr.startWorker(getattr(self,("%s_" % proj)+ "refresh_gui"), getattr(self,("%s_" % proj)+ "refresh_mysql"))#, wargs=(), jobID = self.JobID)
        
        
        setattr(self,("%s_" % proj) + "bg_thread_timer",wx.Timer(self))
        
        setattr(self,("%s_" % proj) + "thread_abortEvent",dr.AbortEvent())
        getattr(self,("%s_" % proj)+ "thread_abortEvent").clear()
        
        self.Bind(wx.EVT_TIMER,__run,getattr(self,("%s_" % proj)+ "bg_thread_timer"))
        getattr(self,("%s_" % proj)+ "bg_thread_timer").Start(self.timer_interval)
        self.log.log("proj [%s] background thread timer is running." % proj)

    def refresh_xml(self):
        
        self.proj = self.proj_def[int(self.nb.GetSelection())]
        
        if self.proj == "tianjie":
            self.cfg_path = r"./xml/tianjie/"
            self.prop_file = self.cfg_path  + "prop.xml"
            self.skill_file = self.cfg_path + "attackskills.xml"
            self.equip_file = self.cfg_path + "equipment.xml"
            self.equips_cfg = self.xml_request.getxml(self.equip_file)
        elif self.proj == "ssdz":
            self.cfg_path = r"./xml/ssdz/"
            self.prop_file = self.cfg_path+"props.xml"
            self.skill_file = self.cfg_path+"skills.xml"
            #self.weapon_file = self.cfg_path+"gears.xml"
            #self.equips_cfg = self.xml_request.getxml(self.equip_file)
            
        self.props_cfg  = self.xml_request.getxml(self.prop_file)    
        self.skills_cfg = self.xml_request.getxml(self.skill_file)
         
        
        
        
    def refresh_mysql(self):
        
        self.proj = self.proj_def[int(self.nb.GetSelection())]
        self.db = self.xml_request.read_cfg()[self.proj]["database"]
        self.player = {}
        
        if self.proj == "config":
            setattr(self.nb,"tianjie_refresh_mysql_flag",False)
            setattr(self.nb,"ssdz_refresh_mysql_flag",False)
            return
        if getattr(self.nb,("%s_" % self.proj)+ "refresh_mysql_flag"):
            
            st = time.time()
            self.queryname = getattr(self,("%s_" % self.proj)+"search_v").GetValue().strip()
            self.Log.log("refreshing mysql with queryname [%s]" % self.queryname)

            if self.queryname == "":
                self.Log.log("No player name or uc id inputed. query operation is not executed.")
            else:
                for db in self.db:
                    qd = self.mysql_request.refresh(self.proj,db,self.queryname)
                    
                    if qd != None:
                        for k,v in qd.items():
                            self.player[k] = v
                            
                self.Log.log("refresh mysql's action costs time [%s]s" % (time.time()-st))
                
                
    def OnSearch(self,e):
        #self.reset_player_detail_ui()
        self.log.log("start to search...")
        self.proj = self.proj_def[int(self.nb.GetSelection())]
        setattr(self.nb,("%s_" % self.proj) + "refresh_mysql_flag",True)
        
        if getattr(self,("%s_" % self.proj)+ "bg_thread_timer").IsRunning():
            getattr(self,("%s_" % self.proj)+ "thread_abortEvent").set()
            getattr(self,("%s_" % self.proj)+ "bg_thread_timer").Stop()
            dr.startWorker(getattr(self,("%s_" % self.proj)+ "refresh_gui"), getattr(self,("%s_" % self.proj)+ "refresh_mysql"))
        getattr(self,("%s_" % self.proj)+ "bg_thread_timer").Start(self.timer_interval)        
        
        
    def make_ui_code(self,data_label,make_sizer):
        l_names = locals()
        bl = []
        for nline in range(len(data_label)):
            line_box_name = "line_box_%s" % nline            
            l_names[line_box_name] = wx.BoxSizer(wx.HORIZONTAL)            
            for nitem in  range(len(data_label[nline])):
                line_box_info_name = "line_box_info_name_%s_%s" % (nline,nitem)
                line_box_name_value = "line_box_info_vlaue_%s_%s" % (nline,nitem)
                line_box_button = "line_box_info_button_%s_%s" % (nline,nitem)
                if "button|" in data_label[nline][nitem]:
                    l_names[line_box_button] = wx.Button(self,-1,data_label[nline][nitem].split('|')[1])
                    bl.append(line_box_button)
                else:
                    l_names[line_box_info_name] = wx.StaticText(self,-1, data_label[nline][nitem])
                    l_names[line_box_name_value] = wx.TextCtrl(self,-1,"",style= wx.TE_READONLY|wx.TE_RICH2)#16 is readonly
                    l_names[line_box_info_name].SetMinSize((80,20))
                    l_names[line_box_name_value].SetMinSize((110,20))
                    l_names[line_box_name_value].SetBackgroundColour("#F2F2F2")
                    l_names[line_box_name].Add(l_names[line_box_info_name],0,wx.EXPAND|wx.RIGHT,5)
                    l_names[line_box_name].Add(l_names[line_box_name_value],0,wx.EXPAND|wx.RIGHT,5)
            make_sizer.Add(l_names[line_box_name],0,wx.EXPAND,5)
        bl_sizer = wx.BoxSizer(wx.HORIZONTAL) 
        for k in bl:bl_sizer.Add(l_names[k],0,wx.EXPAND|wx.RIGHT,5)
        make_sizer.Add(bl_sizer,0,wx.CENTER|wx.ALIGN_RIGHT,5)
        return l_names
    
    def make_grid_code(self,Tags):
        colsize = [(0,60),
                   (1,100),
                   (2,50),
                   (3,60)]
        dt = [GRID_STRING,GRID_STRING,GRID_STRING,GRID_STRING]
        return CustTableGrid(self,Tags,dt,colsize,[]) 

    def refresh_data_player_prop_ui(self):
        
        show_data = []
        try:
            props_data = self.player[self.tb_player_prop]
        except:
            props_data = {}
            
        if props_data != {}:
            
            k = props_data.keys()
            k.sort()
            for n in k:
                m = props_data[n]
                k1 = m.keys()
                show_data.append((m[[x for x in k1 if "id" == x.lower()][0]],\
                                  self.props_cfg[m[[x for x in k1 if "prop" in x.lower() and "id" in x.lower()][0]]].attrib["name"],\
                                  m[[x for x in k1 if "prop" in x.lower() and "id" in x.lower()][0]],\
                                  m[[x for x in k1 if "count" == x.lower()][0]]))
        
        show_data.sort(lambda x,y:cmp(int(x[2]),int(y[2])))
        
        for n in range(len(show_data),50):
            show_data.append(("","","",""))
        for nrow in range(len(show_data)):
            for ncol in range(len(show_data[nrow])):
                self.item_g.SetValue(nrow,ncol,str(show_data[nrow][ncol]).decode('utf-8'))
                
                
    def refresh_data_player_detail_ui(self):   
        self.proj = self.proj_def[int(self.nb.GetSelection())]
        self.db = self.xml_request.read_cfg()[self.proj]["database"]
        
        player_detail_ui_values = [t for t in self.player_detail_ui.keys() if  "line_box_info_vlaue_" in t]
        player_detail_ui_values.sort()
        
        
        player_detail_ui_tags = [t for t in self.player_detail_ui.keys() if  "line_box_info_name_" in t]
        player_detail_ui_tags.sort()
        
        player_detail_ui_value_tag = [t for t in self.player_detail_ui_value_tag if "self." not in t]
        
        if 1:
            self.tb_player = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player"][0]
            self.tb_player_prop = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player_prop"][0]
            self.tb_player_skill = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player_skill"][0]
            if self.proj == "tianjie":
                self.tb_player_equip = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player_equipment"][0]
            self.player_id = self.player[self.tb_player]["row_1"]["id"]        

        try:
            self.tb_player = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player"][0]
            self.tb_player_prop = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player_prop"][0]
            self.tb_player_skill = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player_skill"][0]
            if self.proj == "tianjie":
                self.tb_player_equip = [x for x in  self.xml_cfg[self.proj].keys() if x[2:] == "player_equipment"][0]
            self.player_id = self.player[self.tb_player]["row_1"]["id"]
        except:
            self.log.log("read xml config error.")
            return

        for ntag in range(len(player_detail_ui_values)):
            nums = re.findall(r"\d+",player_detail_ui_values[ntag])
            if len(nums) != 2:# check if there's 2 number in names, cause it contains row number and col number 
                print "met an fatal error of tag configuration"
                continue
            
            tags = [x for x in player_detail_ui_value_tag[ntag].split(',') if x.strip() != ""]
            
            if tags == []:
                continue
            
            NewData = []
            for nitem in tags:
                s = nitem.split('.')
                tb = s[0]
                tag = s[1]                    
                argu_key = None
                if self.player[tb] != {}:
                    if len(s) > 2:
                        argu_key = s[2]
                        argu_v = s[3]
                    if argu_key == None:
                        ag = str(self.player[tb]["row_1"][tag]).decode("utf-8")
                        if tag == "role":
                            if ag == "2":
                                ag = "2 --> 法师".decode("utf-8")
                            elif ag == "1":
                                ag = "1 --> 战士".decode("utf-8")
                            #elif ag == "2":
                                #ag = "箭灵_2".decode("utf-8")
                        NewData.append(ag)
                    else:
                        d = self.player[tb]
                        
                        ag = [x[tag] for x in d.values() if str(x[argu_key]) == (argu_v)]
                        
                        NewData.append(str(ag).decode("utf-8"))
                        
            NewData = '/'.join(NewData)
            OldData = self.player_detail_ui[player_detail_ui_values[ntag]].GetValue()

            self.player_detail_ui[player_detail_ui_values[ntag]].SetValue(NewData)
            if OldData != "" and OldData != NewData:
                self.player_detail_ui[player_detail_ui_values[ntag]].SetStyle(0, 47, wx.TextAttr("RED", wx.NullColour))
            else:
                self.player_detail_ui[player_detail_ui_values[ntag]].SetStyle(0, 47, wx.TextAttr("#228B22",wx.NullColour))
                

    def refresh_data_player_skill_ui(self):
        show_data = []
        try:
            skills_data = self.player[self.tb_player_skill]
        except:
            skills_data = {}
        
        if skills_data != {}:
            k = skills_data.keys()
            k.sort()
            for n in k:
                m = skills_data[n]
                k1 = m.keys()
                
                show_data.append((m[[x for x in k1 if "id" == x.lower()][0]],\
                                  self.skills_cfg[m[[x for x in k1 if "skill" in x.lower() and "id" in x.lower()][0]]].attrib["name"],\
                                  m[[x for x in k1 if "skill" in x.lower() and "id" in x.lower()][0]],\
                                  m[[x for x in k1 if "level" == x.lower()][0]]))
        
        show_data.sort(lambda x,y:cmp(int(x[2]),int(y[2])))
        
        for n in range(len(show_data),99):
            show_data.append(("","","",""))
        for nrow in range(len(show_data)):
            for ncol in range(len(show_data[nrow])):
                self.skill_g.SetValue(nrow,ncol,str(show_data[nrow][ncol]).decode('utf-8'))              
                